package com.qfmy.baseCode.builder;

import ch.qos.logback.classic.Logger;
import com.qfmy.baseCode.consts.CommonPropertiesConst;
import com.qfmy.baseCode.consts.PathAndPackageConst;
import com.qfmy.baseCode.utils.PropertiesUtils;
import com.qfmy.baseCode.utils.ReadAndWriteUtils;
import lombok.Cleanup;
import lombok.Data;
import lombok.SneakyThrows;
import org.jetbrains.annotations.NotNull;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.util.ArrayList;
import java.util.List;

/**
 * @author: 廖志伟
 * @date: 2024-11-13
 * 创建一些基础的类
 */
@Data
@SuppressWarnings("all")
public class BuilderBase {
    //定义一个日志变量
    private static final Logger log = (Logger) LoggerFactory.getLogger(BuilderBase.class);
    //定义一个扩展类的包
    private String extendPackage;
    //定义一个变量判断是用什么方式进行登入
    private String loginType;
    //定义一个变量判断是否要生成redis
    private boolean redis;
    //定义一个变量用来存放是否要进行登入
    private boolean login;
    //定义一个基础包
    private String basePackage;
    //定义一个querry的路径
    private String queryPath ;
    //定义一个vo的路径
    private String voPath;
    //定义一个日期的路径
    private String dataPath;
    //定义一个枚举类的路径
    private String enumPath;
    //定义一个mapper的路径
    private String mapperPath ;
    //定义一个分页查询索要的路径
    private String pagePath ;
    //定义一个分页查询的枚举类
    private String pageEnum;
    //定义一个枚举类的路径
    private String PageEnumPath;
    //定义一个Service所在的路径
    private String servicePath;
    //定义一个配置类所在的路径
    private String configPath;
    //定义一个拦截器所在的路径
    private String interceptorPath;
    //定义一个公共的类所在的包
    private String commomPackage;
    //的定义一个响应结果所在的包
    private String resultPackage;
    //定义常量所在的包
    private String constantPackage;
    //定义jwt所在的包
    private String jwtPackage;
    //定义一个全局异常处理器所在的包
    private String exceptionPackage;
    //响应结果所在的路径
    private String resultPath ;
    //定义一个常量类所在的路径
    private String constantPath;
    //定义一个jwt工具类所在的路径
    private String jwtPath;
    //定义一个全局异常处理器所在的路径
    private String exceptionPath ;
    //定义一个minio配置所在的路径
    private String minioPath;
    //定义一个短信验证的路径
    private String smsPath ;
    //定义一个验证码的路径
    private String captchaPath;
    //定义一个redis的路径
    private String redisPath;
    //定义一个注册的方式
    private String registerType;
    //邮箱的路径
    private String emailPath;


    public BuilderBase(@NotNull String extendPackage, String loginType, boolean redis, boolean login, @NotNull String basePackage, @NotNull String commomPackage,String registerType){
        this.extendPackage = extendPackage;
        this.loginType = loginType;
        this.redis = redis;
        this.login = login;
        this.basePackage = basePackage;
        this.commomPackage = commomPackage;
        this.queryPath = PathAndPackageConst.PATH_BASE +  extendPackage.replace(".", "/");
        this.voPath = PathAndPackageConst.PATH_BASE  + basePackage.replace(".","/") + "/" + PropertiesUtils.getProperty("package.vo").replace(".", "/");
        this.enumPath = CommonPropertiesConst.BASE_PATH + commomPackage.replace(".","/")  + "/enmus";
        this.dataPath = CommonPropertiesConst.BASE_PATH + commomPackage.replace(".","/")  + "/utils";
        this.mapperPath =  PathAndPackageConst.PATH_BASE + basePackage.replace(".","/") + "/mapper";
        this.pagePath = PathAndPackageConst.PATH_BASE +  basePackage.replace(".","/")+ "/" + PropertiesUtils.getProperty("package.page").replace(".", "/");
        this.pageEnum = commomPackage + "." + PropertiesUtils.getProperty("package.pageSize");
        this.PageEnumPath = CommonPropertiesConst.BASE_PATH  + commomPackage.replace(".","/")  + "/" + PropertiesUtils.getProperty("package.pageSize");
        this.servicePath = PathAndPackageConst.PATH_BASE + basePackage.replace(".", "/") + "/" + PropertiesUtils.getProperty("package.service");
        this.configPath = PathAndPackageConst.PATH_BASE + basePackage.replace(".","/")  + "/config";
        this.interceptorPath = PathAndPackageConst.PATH_BASE + basePackage.replace(".","/")  + "/interceptor";
        this.resultPackage = commomPackage + ".result";
        this.constantPackage = commomPackage + ".constant";
        this.jwtPackage = commomPackage + ".utils";
        this.exceptionPackage = commomPackage + ".exception";
        this.resultPath = CommonPropertiesConst.BASE_PATH + commomPackage.replace(".","/") + "/result";
        this.constantPath = CommonPropertiesConst.BASE_PATH + commomPackage.replace(".","/") + "/constant";
        this.jwtPath = CommonPropertiesConst.BASE_PATH + commomPackage.replace(".","/") + "/utils";
        this.exceptionPath = CommonPropertiesConst.BASE_PATH + commomPackage.replace(".","/") + "/exception";
        this.minioPath = CommonPropertiesConst.BASE_PATH + commomPackage.replace(".","/") + "/minio";
        this.smsPath = CommonPropertiesConst.BASE_PATH + commomPackage.replace(".","/") + "/sms";
        this.captchaPath = CommonPropertiesConst.BASE_PATH + commomPackage.replace(".","/") + "/utils";
        this.redisPath = CommonPropertiesConst.BASE_PATH + commomPackage.replace(".","/") + "/redis";
        this.registerType = registerType;
        this.emailPath = CommonPropertiesConst.BASE_PATH + commomPackage.replace(".","/") + "/email";
    }

    public  void execute() {
        //定义一个集合,用来存放要生成的package包
        List<String> packages =  new ArrayList<>();
        packages.add("package " + commomPackage + ".enums");
        //创建格式式化字符工具类
        build(packages,enumPath,"DateTimePatternEnum");
        //清理集合
        packages.clear();
        packages.add("package " + commomPackage + ".utils");
        //创建DateUtil类
        build(packages,dataPath, "DateUtil");
        //清理集合
        packages.clear();
        packages.add("package " + basePackage + ".mapper");
        //创建Mapper基类
        build(packages,mapperPath, "BaseMapper");
        //清理集合
        packages.clear();
        //生成PageSizeEnum类
        packages.add("package " + pageEnum);
        build(packages,PageEnumPath, "PageSize");
        //清理集合
        packages.clear();
        //生成分页查询类
        packages.add("package " + commomPackage + "." + PropertiesUtils.getProperty("package.page") );
        packages.add("import " + pageEnum + "." + "PageSize");
        build(packages,pagePath, "SimplePage");
        //清理集合
        packages.clear();
        //生成BaseQuery的基类
        packages.add("package " + extendPackage );
        packages.add("import " + basePackage + "." + PropertiesUtils.getProperty("package.page") + "." + "SimplePage");
        build(packages,queryPath, "BaseQuery");
        //清理集合
        packages.clear();
        //生成PaginationResultVo
        packages.add("package " + basePackage + "." + PropertiesUtils.getProperty("package.page"));
        build(packages,pagePath, "PaginationResultVo");
        //清理集合
        packages.clear();
        //生成ResultCodeEnum类
        packages.add("package " + resultPackage);
        build(packages,resultPath, "ResultCodeEnum");
        //清理集合
        packages.clear();
        //生成Result结果类
        packages.add("package " + resultPackage );
        build(packages,resultPath, "Result");
        //清理集合
        //生成Const常量类
        packages.clear();
        packages.add("package " + constantPackage );
        build(packages,constantPath, "LoginMessageConst");
        //清理集合
        packages.clear();
        //生成全局异常处理器
        packages.add("package " + exceptionPackage );
        //导入包
        packages.add("import " + resultPackage  + ".ResultCodeEnum");
        //构建类
        build(packages,exceptionPath, "BaseException");
        //清理集合
        packages.clear();
        //生成全局异常处理器
        packages.add("package " + exceptionPackage );
        //导入包
        packages.add("import " + resultPackage  + ".Result");
        build(packages,exceptionPath, "GlobalExceptionHandler");
        //清理集合
        packages.clear();
        //生成JwtUtil类
        packages.add("package " + jwtPackage );
        //导入包
        packages.add("import " + resultPackage+ ".ResultCodeEnum");
        packages.add("import " + exceptionPackage + ".BaseException");
        build(packages,jwtPath, "JwtUtil");
        //清理集合
        packages.clear();
        //生成标识登入用户信息的类->这个类是用来存放从jwt类名获取的用户id和名称
        packages.add("package " + constantPackage);
        build(packages,constantPath, "LoginUser");
       //判断是否要生成redis
        if(isRedis())
        {
            //清理集合
            packages.clear();
            //生成redis常量类
            packages.add("package " + commomPackage  + ".redis");
            build(packages,redisPath, "RedisConstant");
            //清理集合
            packages.clear();
            //生成redis工具类
            packages.add("package " + commomPackage  + ".redis");
            build(packages,redisPath, "RedisUtils");
            //清理集合
            packages.clear();
            //创建一个redis的配置类
            packages.add("package " + commomPackage  + ".redis");
            build(packages,redisPath, "RedisConfig");
            //清理集合
            packages.clear();
        }
        //清理集合
        packages.clear();
        //生成LoginUserHolder类 ->当前线程中存放用户信息的类
        packages.add("package " + constantPackage);
        build(packages,constantPath, "LoginUserHolder");
        //判断一下是否要生成minio
        if(login){
            //清理集合
            packages.clear();
            //定义登入状态的枚举类
            packages.add("package " + commomPackage  + ".enums");
            build(packages,enumPath,"LoginStatusEnum");
            //清理集合
            packages.clear();
            //生成MinioPropertis类
            packages.add("package " + commomPackage + ".minio" );
            build(packages,minioPath, "MinioProperties");
            //清理集合
            packages.clear();
            //生成MinioConfig配置类
            packages.add("package " + commomPackage +".minio");
            build(packages,minioPath, "MinioConfig");
            //账号密码登入+图形验证码进行登入
            if(loginType.equals("1")){
                //清理集合
                packages.clear();
                //生成验证码生成器
                packages.add("package " + jwtPackage);
                build(packages,captchaPath, "CodeUtils");
                //清理集合
                packages.clear();
                //清理集合
                packages.clear();
                //生成图形验证码
                packages.add("package " + commomPackage + ".utils" );
                build(packages,captchaPath, "Captcha");
            }
            //手机号登入+短信验证码进行登入
            else if(loginType.equals("2")){
                //清理集合
                packages.clear();
                //生成使用手机号登入的实体类
                packages.add("package " + basePackage + "." + PropertiesUtils.getProperty("package.vo"));
                build(packages,voPath, "LoginVo");
                //清理集合
                packages.clear();
                //生成SmsProperties类
                packages.add("package " + commomPackage + ".ssm");
                build(packages,smsPath, "AliyunSMSProperties");
                //清里集合
                packages.clear();
                //生成SmsConfig类
                packages.add("package " + commomPackage + ".ssm");
                build(packages,smsPath, "AliyunSMSConfig");
                //清理集合
                packages.clear();
                //生成短信验证的Service
                packages.add("package " + basePackage + ".service");
                build(packages,servicePath , "SmsService");
                //清理集合
                packages.clear();
                //生成短信验证的ServiceImpl
                packages.add("package " + basePackage + ".service.impl");
                packages.add("import " + basePackage + ".service.SmsService");
                build(packages,servicePath + "/impl", "SmsServiceImpl");
                //清理集合
                packages.clear();
            }
            //微信扫码登入 + 账号密码登入
            else if(loginType.equals("3"))
            {
                //清理集合
                packages.clear();
                //生成验证码生成器
                packages.add("package " + jwtPackage);
                build(packages,captchaPath, "CodeUtils");
                //清理集合
                packages.clear();
                //清理集合
                packages.clear();
            }
        }
        //判断注册的方式 ->账号 + 密码 + 邮箱
        if(registerType.equals("3"))
        {
            //清理集合
            packages.clear();
            //生成邮箱的配置类
            packages.add("package " + commomPackage + ".email");
            build(packages,emailPath, "EmailProperties");
            //清理集合
            packages.clear();
            //生成邮箱的信息类
            packages.add("package " + commomPackage + ".email");
            build(packages,emailPath, "SysSettingEmail");
            //清理集合
            packages.clear();
            //生成邮箱的发送类
            packages.add("package " + commomPackage + ".email");
            build(packages,emailPath,"redisEmail");
            //清理集合
            packages.clear();
        }
        //定义拦截器
        packages.clear();
        packages.add("package " + basePackage + ".interceptor" );
        packages.add("import " + commomPackage + ".redis.*");
        packages.add("import " + constantPackage + ".LoginUserHolder");
        packages.add("import " + exceptionPackage + ".BaseException");
        packages.add("import " + resultPackage + ".ResultCodeEnum");
        packages.add("import " + jwtPackage + ".JwtUtil");
        build(packages,interceptorPath, "AuthenticationInterceptor");
        //清理集合
        packages.clear();
        //定义一个配置类将拦截器注册到容器中
        packages.add("package " + basePackage + ".config");
        packages.add("import " + basePackage + ".interceptor" + ".AuthenticationInterceptor");
        build(packages,configPath, "WebMvcConfig");




    }

    /**
     * 创建DateUtil类
     * @param packages
     * @param filePath
     * @param filename
     */
    @SneakyThrows
    public  void build(List<String> packages, String filePath, String filename) {
            //创建文件对象
            File fileds = new File(filePath);
            //创建读写工具类
            ReadAndWriteUtils read = new ReadAndWriteUtils();
            //判断文件是否存在
            if (!fileds.exists()) {
                //创建文件夹
                fileds.mkdirs();
            }
            File javafile = new File(filePath + "/" + filename + ".java");
            @Cleanup BufferedWriter bw = null;
            @Cleanup BufferedReader br = null;
            try {
                read.write(javafile);
                bw = read.getBw();
                String path = "template/" + filename + ".txt";
                //获取模板路径
                String templatePath = BuilderBase.class.getClassLoader().getResource(path).getPath();
                //读取模板内容
                read.read(templatePath);
                 br = read.getBr();
                //在写类之前进行包的导入
                for (var p : packages)
                {
                    bw.write( p + ";" + "\n");
                }
                String line = null;
                //边读边写
                while ((line = br.readLine()) != null) {
                    bw.write(line + "\n");
                }
                //刷新缓冲区
                bw.flush();
            }catch (Exception e)
            {
                log.error("创建文件失败",e);
            }
        }
}
